home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 301-325 / disk_314 / a68k / a68k.lzh / Adirect.c < prev    next >
C/C++ Source or Header  |  1990-02-05  |  25KB  |  863 lines

  1. /*------------------------------------------------------------------*/
  2. /*                                    */
  3. /*            MC68000 Cross Assembler                */
  4. /*                                    */
  5. /*        Copyright (c) 1985 by Brian R. Anderson            */
  6. /*                                    */
  7. /*         Assembler directive processing - January 9, 1990        */
  8. /*                                    */
  9. /*   This program may be copied for personal, non-commercial use    */
  10. /*   only, provided that the above copyright notice is included        */
  11. /*   on all copies of the source code.  Copying for any other use   */
  12. /*   without the consent of the author is prohibited.            */
  13. /*                                    */
  14. /*------------------------------------------------------------------*/
  15. /*                                    */
  16. /*        Originally published (in Modula-2) in            */
  17. /*        Dr. Dobb's Journal, April, May, and June 1986.          */
  18. /*                                    */
  19. /*     AmigaDOS conversion copyright 1990 by Charlie Gibbs.        */
  20. /*                                    */
  21. /*------------------------------------------------------------------*/
  22.  
  23. #include <stdio.h>
  24. #include "A68kdef.h"
  25. #include "A68kglb.h"
  26.  
  27. /* Functions */
  28. extern int  LineParts(), Instructions();
  29. extern int  GetInstModeSize(), GetMultReg(), CountNest();
  30. extern int  ReadSymTab(), GetArgs(), GetAReg(), OpenIncl();
  31. extern long AddrBndW(), AddrBndL(), GetValue(), CalcValue();
  32. extern char *AddName(), *GetField();
  33. extern struct SymTab *NextSym();
  34. extern struct SymTab **HashIt();
  35.  
  36.  
  37.  
  38. int ObjDir (dummy) int dummy;
  39. /* Generates Object Code for Assembler Directives. */
  40. {
  41.     register char *s, *t;
  42.     register int i, j;
  43.     int  oploc;
  44.     long templong;
  45.     char tempop[MAXLINE], delim;
  46.     struct SetFixup *sf;
  47.  
  48.     switch (Dir) {
  49.  
  50.     case Org:                        /* ORG, RORG */
  51.     PrntAddr = MakeHunk = TRUE;
  52.     FwdLim1     = FwdBranch;    /* Clear forward branch controls. */
  53.     FwdFixLimit = FwdBranchFix;
  54.     templong = GetValue (SrcOp, SrcLoc);
  55.     if (DefLine2 >= LineCount) {
  56.         Error (SrcLoc, FwdRef);    /* Illegal forward reference */
  57.         break;
  58.     }
  59.     if (OpCode[0] == 'R') {                /* RORG */
  60.         if (Hunk2 != ABSHUNK) {
  61.         Error (SrcLoc, RelErr);    /* RORG needs an absolute value. */
  62.         break;
  63.         }
  64.     } else if (Hunk2 != CurrHunk) {
  65.         Error (SrcLoc, RelErr);    /* We can't ORG out of a hunk. */
  66.         break;
  67.     }
  68.  
  69.     if ((!Pass2 || (HunkType == HunkBSS))
  70.     && (templong < AddrCnt)    /* If we're ORGing to a lower address  */
  71.     && (AddrCnt > OrgHigh))    /*  and this is the highest we've been */
  72.         OrgHigh = AddrCnt;    /*  remember how far we got.           */
  73.  
  74.     AddrCnt = templong;    /* Update the location counter. */
  75.     OrgFlag = TRUE;        /* Indicate object fixups are needed. */
  76.     if (HunkType == HunkNone) {
  77.         DoSection ("", 0, "", 0, "", 0);    /* Start unnamed CODE section. */
  78.         MakeHunk = TRUE;
  79.     }
  80.     break;
  81.  
  82.     case Equ:                        /* EQU */
  83.     if (Label[0] == '\0')
  84.         Error (0, NeedLab);        /* We need a label. */
  85.     ObjSrc = GetValue (SrcOp, SrcLoc);
  86.     if (DefLine2 >= LineCount)
  87.         Error (SrcLoc, FwdRef);    /* Illegal forward reference */
  88.     Src.Hunk = Hunk2;
  89.     PrntAddr = MakeHunk = TRUE;
  90.     break;
  91.  
  92.     case DC:                        /* DC */
  93.     if ((Size == Word) || (Size == Long))
  94.         AddrCnt = AddrBndW (AddrCnt);
  95.     s = Line + SrcLoc;
  96.     while (!isspace(*s) && (*s != '\0') && (*s != ';')) {
  97.         oploc = s - Line;
  98.         if (((*s == '\'') || (*s == '"'))    /* String */
  99.         && (Size == Byte)) {
  100.         delim = *s++;            /* Get the delimiter. */
  101.         while (1) {
  102.             if (*s == '\0') {        /* No closing delimiter */
  103.             Error (s-Line, NoStrEnd);
  104.             break;
  105.             }
  106.             if (*s == delim) {        /* End of string? */
  107.             if (*(++s) != delim)    /* Check next character. */
  108.                 break;        /* End of string */
  109.             }    /* Otherwise it's an apostrophe in the string. */
  110.             Src.Hunk = ABSHUNK;        /* Absolute value */
  111.             ObjString[nX++] = *s++;    /* Current character */
  112.         }
  113.         } else {            /* It's not a string constant. */
  114.         s = GetField (s, SrcOp);
  115.         ObjSrc = GetValue (SrcOp, oploc);    /* Value */
  116.         if ((Src.Hunk = Hunk2) != ABSHUNK) {    /* Hunk number */
  117.             templong = AddrCnt + nX;        /* Relocatable */
  118.             PutRel (templong, Hunk2, Size);
  119.         }
  120.         if (Size == 4) {
  121.             ObjString[nX++] = (ObjSrc >> 24) & 0x00FF;
  122.             ObjString[nX++] = (ObjSrc >> 16) & 0x00FF;
  123.         }
  124.         if (Size >= 2)
  125.             ObjString[nX++] = (ObjSrc >> 8) & 0x00FF;
  126.         ObjString[nX++] = ObjSrc & 0x00FF;
  127.         if (Size == 2)
  128.             templong = 0xFFFF0000L;
  129.         else if (Size == 1)
  130.             templong = 0xFFFFFF00L;
  131.         if (Size < 4)
  132.             if (((ObjSrc & templong) != 0)
  133.             && ((ObjSrc & templong) != templong))
  134.             Error (s-Line, SizeErr);
  135.         }
  136.         if (*s == ',')
  137.         s++;            /* Skip over separator. */
  138.     }
  139.     if ((!isspace(*s) && (*s != '\0') && (*s != ';'))
  140.     || (SrcLoc == 0))
  141.         Error (s-Line, OperErr);    /* Statement didn't end properly. */
  142.     AddrAdv = InstSize = nX;
  143.     PrntAddr = MakeHunk = TRUE;
  144.     break;
  145.  
  146.     case DS:                        /* DS */
  147.     if (DestLoc != 0) {
  148.         Error (DestLoc, OperErr);    /* Only one operand is allowed. */
  149.         PrntAddr = MakeHunk = TRUE;
  150.         break;
  151.     }
  152.     AddrAdv = GetValue (SrcOp, SrcLoc);
  153.     if (DefLine2 >= LineCount) {
  154.         Error (SrcLoc, FwdRef);    /* Illegal forward reference */
  155.         AddrAdv = 0;
  156.     }
  157.     if (Hunk2 != ABSHUNK)
  158.         Error (SrcLoc, AbsReq);    /* Count must be absolute. */
  159.  
  160.     if (Size == Word) {        /* Words */
  161.         AddrCnt = AddrBndW (AddrCnt);
  162.         AddrAdv <<= 1;
  163.     }
  164.     if (Size == Long) {        /* Long words */
  165.         AddrCnt = AddrBndW (AddrCnt);
  166.         AddrAdv <<= 2;
  167.     }
  168.     if (Pass2 && (HunkType != HunkBSS)) {    /* If this isn't      */
  169.         templong = AddrAdv;            /*  a BSS hunk,       */
  170.         while (templong >= 4) {        /*  generate zeros    */
  171.         AppendSdata (0L, 4);        /*  to fill the area. */
  172.         templong -= 4;
  173.         }
  174.         if (templong > 0) {
  175.         i = templong;
  176.         AppendSdata (0L, i);
  177.         }
  178.     }
  179.     PrntAddr = MakeHunk = TRUE;
  180.     break;
  181.  
  182.     case Even:                        /* EVEN */
  183.     FwdLim1     = FwdBranch;    /* Clear forward branch controls. */
  184.     FwdFixLimit = FwdBranchFix;
  185.     AddrCnt = AddrBndW (AddrCnt);
  186.     PrntAddr = MakeHunk = TRUE;
  187.     break;
  188.  
  189.     case End:                        /* END */
  190.     if (Pass2)
  191.         if (SrcOp[0] != '\0')
  192.         EndAddr = GetValue (SrcOp, SrcLoc);
  193.         else
  194.         EndAddr = 0;
  195.     PrntAddr = MakeHunk = TRUE;
  196.     break;
  197.  
  198.     case Xdef:                        /* XDEF */
  199.     case Public:                    /* PUBLIC */
  200.     if (SFormat)
  201.         Error (OpLoc, NotSFmt);        /* Not in S-format */
  202.     s = Line + SrcLoc;
  203.     while (!isspace(*s) && (*s != '\0') && (*s != ';')) {
  204.         oploc = s - Line;
  205.         s = GetField (s, SrcOp);        /* Get a symbol. */
  206.         if (ReadSymTab (SrcOp)) {
  207.         if (!Pass2) {
  208.             if ((Sym->Flags & 0x61) == 0) {
  209.             Sym->Flags |= 2;    /* Set XDEF flag. */
  210.             if (OpCode[0] == 'P') {
  211.                 Sym->Flags |= 0x80;    /* It's defined as PUBLIC. */
  212.             }
  213.             }
  214.         } else {
  215.             if (Sym->Defn != LineCount)    /* If not PUBLIC->XREF */
  216.             AddRef (LineCount);    /*  it's a reference.  */
  217.             if (Sym->Defn == NODEF)
  218.             Error (oploc, Undef);    /* It never got defined. */
  219.             else if (Sym->Flags & 0x60)
  220.             Error (oploc, AddrErr);    /* Can't XDEF a register. */
  221.         }
  222.         } else if (!Pass2) {        /* It's not yet defined. */
  223.         if (OpCode[0] == 'P') {        /* Treat PUBLIC as XREF. */
  224.             AddSymTab (SrcOp, 0L, 0L ,LineCount, 0x81);
  225.             Sym->Hunk = ~((long) Sym->Nam);
  226.         } else {
  227.             AddSymTab (SrcOp, 0L, CurrHunk, NODEF, 2);    /* XDEF */
  228.         }
  229.         }
  230.         if (*s == ',')
  231.         s++;                /* Skip over separator. */
  232.     }
  233.     break;
  234.  
  235.     case Xref:                        /* XREF */
  236.     if (SFormat)
  237.         Error (OpLoc, NotSFmt);        /* Not in S-format */
  238.     s = Line + SrcLoc;
  239.     while (!isspace(*s) && (*s != '\0') && (*s != ';')) {
  240.         oploc = s - Line;
  241.         s = GetField (s, SrcOp);
  242.         if (Pass2) {
  243.         if (ReadSymTab (SrcOp)) {
  244.             if (Sym->Defn != LineCount) {
  245.             AddRef (LineCount);    /* Ignore extraneous XREF. */
  246.             }
  247.         }
  248.         } else {
  249.         if (!ReadSymTab    (SrcOp)) {    /* Only if not defined */
  250.             AddSymTab (SrcOp, 0L, 0L, LineCount, 1);
  251.             Sym->Hunk = ~((long) Sym->Nam);
  252.         }
  253.         }
  254.         if (*s == ',')
  255.         s++;            /* Skip over separator. */
  256.     }
  257.     break;
  258.  
  259.     case Page:                        /* PAGE */
  260.     if (Pass2 && (LineCount > 1))    /* Ignore PAGE at start of file. */
  261.         LnCnt = LnMax;        /* Resume on a new page. */
  262.     break;
  263.  
  264.     case DoList:                    /* LIST */
  265.     ListOff = FALSE;
  266.     if (!Pass2 && !SuppList && (IncStart != 0)) {
  267.         IncStart = 0;            /* We can't      */
  268.         if (SkipLim->Set1 != NULL) {    /*  skip this    */
  269.         SetFixLim = SkipLim->Set1;    /*  INCLUDE file */
  270.         SetFixLim++;            /*  in pass 2    */
  271.         }                    /*  (we must     */
  272.     }                    /*  list it).    */
  273.     break;
  274.  
  275.     case NoList:                    /* NOLIST */
  276.     ListOff = TRUE;
  277.     break;
  278.  
  279.     case Space:                        /* SPC */
  280.     if (Pass2 && !ListOff && !SuppList) {
  281.         if (SrcOp[0] != '\0')
  282.         j = GetValue (SrcOp, SrcLoc);    /* Amount to space */
  283.         else
  284.         j = 1;                /* Default to one line. */
  285.         for (i = 0; i < j; i++) {
  286.         if (LnCnt >= LnMax)
  287.             break;            /* Page overflow */
  288.         xputs (&List, "\n");        /* Space one line. */
  289.         }
  290.     }
  291.     break;
  292.  
  293.     case Title:                        /* TTL */
  294.     s = Line + SrcLoc;
  295.     t = TTLstring;
  296.     while (*s && (s < (TTLstring+MAXLINE)))
  297.         *t++ = *s++;        /* Get title string. */
  298.     *t = '\0';
  299.     if (LineCount > 1) {
  300.         LnCnt = LnMax;        /* Skip to a new page. */
  301.     } else {
  302.         if (Pass2) {
  303.         xputs (&List, TTLstring);
  304.         xputs (&List, "\n\n");
  305.         }
  306.         LnCnt += 2;            /* Don't skip at start of file. */
  307.     }
  308.     break;
  309.  
  310.     case Cnop:                        /* CNOP */
  311.     FwdLim1     = FwdBranch;    /* Clear forward branch controls. */
  312.     FwdFixLimit = FwdBranchFix;
  313.     i = TRUE;            /* "Error-free" flag */
  314.  
  315.     ObjSrc = GetValue (SrcOp, SrcLoc);
  316.     if (DefLine2 >= LineCount) {
  317.         Error (SrcLoc, FwdRef);    /* Illegal forward reference */
  318.         i = FALSE;
  319.     }
  320.     if (Hunk2 != ABSHUNK) {
  321.         Error (SrcLoc, AbsReq);    /* Must be absolute! */
  322.         i = FALSE;
  323.     }
  324.  
  325.     ObjDest = GetValue (DestOp, DestLoc);
  326.     if (DefLine2 >= LineCount) {
  327.         Error (DestLoc, FwdRef);    /* Illegal forward reference */
  328.         i = FALSE;
  329.     }
  330.     if (Hunk2 != ABSHUNK) {
  331.         Error (DestLoc, AbsReq);    /* Must be absolute! */
  332.         i = FALSE;
  333.     }
  334.  
  335.     templong = ObjDest;
  336.     while ((templong > 0) && ((templong & 1) == 0))
  337.         templong >>= 1;        /* Shift out low-order zeros. */
  338.     if ((templong != 1) || (ObjDest == 1)) {
  339.         Error (DestLoc, OperErr);    /* DestOp must be a power of 2. */
  340.         i = FALSE;
  341.     }
  342.     if ((ObjSrc & 1) || (ObjSrc >= ObjDest)) {
  343.         Error (SrcLoc, OperErr);    /* SrcOp is odd or out of range. */
  344.         i = FALSE;
  345.     }
  346.  
  347.     if (i) {            /* If no errors so far... */
  348.         AddrCnt = AddrBndW (AddrCnt);
  349.         templong = (AddrCnt & ~(ObjDest-1)) + ObjSrc;
  350.         if (templong < AddrCnt)
  351.         templong += ObjDest;    /* We must advance to here. */
  352.         if ((templong - AddrCnt) < MAXLINE) {
  353.         nX = templong - AddrCnt;
  354.         for (j = 0; j < nX; ) {
  355.             ObjString[j++] = NOP / 256;
  356.             ObjString[j++] = NOP & 255;
  357.         }
  358.         AddrAdv = InstSize = nX;    /* Generate NOPs. */
  359.         PrntAddr = MakeHunk = TRUE;
  360.         } else {
  361.         Error (DestLoc, OperErr);    /* Too many NOPs */
  362.         }
  363.     }
  364.     break;
  365.  
  366.     case Include:                    /* INCLUDE */
  367.     if (Pass2                /* If we can skip */
  368.     && (SkipIdx < SkipLim)            /*  this INCLUDE  */
  369.     && (LineCount == SkipIdx->Start)) {    /*  file in pass  */
  370.         LineCount = SkipIdx->Finish;    /*  2, do so.     */
  371.         MacCount = SkipIdx->MCount;
  372.         if ((sf = SkipIdx->Set1) != NULL) {
  373.         while ((sf >= SetFixLim) && (sf->Sym != NULL)) {
  374.             (sf->Sym)->Val  = sf->Val;    /* Fix up SET symbols. */
  375.             (sf->Sym)->Hunk = sf->Hunk;
  376.             sf--;
  377.         }
  378.         }
  379.         SkipIdx++;
  380.         break;
  381.     }
  382.     if ((Quiet < 0) && (InF->UPtr == 0))
  383.         ShowLine (InF->Line);    /* Show where we are. */
  384.     s = Line + SrcLoc;
  385.     if ((*s == '"') || (*s == '\''))
  386.         s++;            /* Ignore quotes. */
  387.     t = tempop;
  388.     while (!isspace(*s)
  389.     && (*s != '"')
  390.     && (*s != '\'')
  391.     && (*s != '\0'))
  392.         *t++ = *s++;
  393.     *t = '\0';
  394.     if (InF->UPtr == 0) {
  395.         InF->Pos = lseek (In.fd, 0L, 1);
  396.         InF->Pos -= In.Lim-In.Ptr;    /* Position in outer file */
  397.     }
  398.     if (!OpenIncl (tempop, InclList)) {
  399.         Error (SrcLoc, NoIncl);    /* We couldn't open file. */
  400.         InclErrs = TRUE;
  401.         if (InF->UPtr == 0) {
  402.         In.fd = open (InF->NPtr, 0);
  403.         lseek (In.fd, InF->Pos, 0);
  404.         In.Ptr = In.Lim = In.Buf;
  405.         }
  406.         break;            /* Return to outer file. */
  407.     }
  408.     InFNum++;            /* Bump nesting level. */
  409.     if (--InF < LowInF)
  410.         LowInF = InF;
  411.     Heap2Space (strlen(tempop)+1);    /* Check for space. */
  412.     InF->UPtr = 0;            /* It's not a user macro. */
  413.     InF->NPtr = NextFNS;        /* New stack pointer */
  414.     strcpy (NextFNS, tempop);    /* File name */
  415.     NextFNS    += strlen (tempop) + 1;    /* Next available space */
  416.     if (NextFNS > High2)
  417.         High2 = NextFNS;        /* Set high-water mark. */
  418.     InF->NArg = -1;            /* Indicate it's not a macro. */
  419.     InF->Line = 0;            /* Clear line counter. */
  420.     InF->MCnt = MacCount;
  421.  
  422.     if (!Pass2 && (SuppList || ListOff) && (IncStart == 0)) {
  423.         s = (char *) SkipLim + sizeof (struct SkipEnt);
  424.         if (s <= (char *) SetFixLim) {
  425.         SkipLim->Set1 = NULL;    /* Save starting position */
  426.         IncStart = LineCount;    /*  in case we can skip   */
  427.         IncPtr = InF;        /*  this file in pass 2.  */
  428.         }
  429.     }
  430.     break;
  431.  
  432.     case Set:                        /* SET */
  433.     if (Label[0] == '\0')
  434.         Error (0, NeedLab);        /* Need a label */
  435.     ObjSrc = GetValue (SrcOp, SrcLoc);
  436.     if (DefLine2 >= LineCount)
  437.         Error (SrcLoc, FwdRef);    /* Illegal forward reference */
  438.     Src.Hunk = Hunk2;
  439.     if (!ReadSymTab (Label))        /* Make a new entry. */
  440.         AddSymTab (Label, ObjSrc, Src.Hunk, LineCount, 4);
  441.     else if (Sym->Flags & 4) {        /* Re-SET the symbol. */
  442.         Sym->Val = ObjSrc;            /* SET value */
  443.         Sym->Hunk = Src.Hunk;        /* Hunk number */
  444.         Sym->Defn = LineCount;        /* Statement number */
  445.     }
  446.     PrntAddr = MakeHunk = TRUE;
  447.  
  448.     if (!Pass2 && (IncStart != 0)) {
  449.         if ((sf = SkipLim->Set1) != NULL) {
  450.         while (sf >= SetFixLim) {
  451.             if (sf->Sym != Sym) {
  452.             sf--;
  453.             } else {
  454.             sf->Val  = Sym->Val;    /* Update an        */
  455.             sf->Hunk = Sym->Hunk;    /*  existing entry. */
  456.             return (Set);
  457.             }
  458.         }
  459.         }
  460.         sf = SetFixLim;
  461.         sf--;
  462.         s = (char *) SkipLim + sizeof (struct SkipEnt);
  463.         if (s > (char *) sf) {
  464.         IncStart = 0;        /* There's no room for set symbol. */
  465.         if (SkipLim->Set1 != NULL) {
  466.             SetFixLim = SkipLim->Set1;
  467.             SetFixLim++;
  468.         }
  469.         } else {
  470.         if (SkipLim->Set1 == NULL)
  471.             SkipLim->Set1 = sf;    /* First SET symbol in INCLUDE */
  472.         sf->Sym  = Sym;
  473.         sf->Val  = Sym->Val;    /* Save SET symbol value */
  474.         sf->Hunk = Sym->Hunk;    /*  and hunk.            */
  475.         SetFixLim = sf;
  476.         }
  477.     }
  478.     break;
  479.  
  480.     case Macro:                        /* MACRO */
  481.     if (Label[0] == '\0')
  482.         Error (0, NeedLab);        /* Need a label */
  483.  
  484.     s = Label;
  485.     t = tempop;
  486.     *t++ = ' ';            /* Prepend name with a */
  487.     while (*s) {            /*  blank and convert  */
  488.         *t++ = toupper (*s);    /*  it to upper case.  */
  489.         s++;
  490.     }
  491.     *t = '\0';
  492.  
  493.     if (!Pass2) {            /* Pass 1 */
  494.         if (!ReadSymTab (tempop))        /* Save MACRO name. */
  495.         AddSymTab (tempop, 0L, 0L, LineCount, 8);
  496.         Sym->Hunk = (long) AddName(Line,1);    /* Save MACRO stmt. */
  497.     } else {            /* Pass 2 */
  498.         ReadSymTab (tempop);
  499.         if (Sym->Defn != LineCount) {
  500.         Error (LabLoc, DupMac);        /* Duplicate MACRO */
  501.         AddRef (LineCount);
  502.         }
  503.         WriteListLine (&List);        /* Echo MACRO. */
  504.     }
  505.  
  506.     i = 0;                /* IF nest counter */
  507.     while (1) {            /* Process macro body. */
  508.         if (LineParts (dummy)) {
  509.         Error (OpLoc, NoENDM);    /* Premature EOF */
  510.         i = 0;
  511.         break;
  512.         }
  513.         if ((i += CountNest (OpCode)) < 0) {
  514.         Error (OpLoc,ManyENDC);    /* Unmatched ENDC */
  515.         i = 0;
  516.         }
  517.         if (!Pass2)
  518.         AddName (Line, 2);    /* Store a line. */
  519.         if (strcmp (OpCode, "ENDM") == 0)
  520.         break;            /* Main program echoes ENDM. */
  521.         if (Pass2)
  522.         WriteListLine (&List);    /* Echo a line. */
  523.     }
  524.     if (i > 0)
  525.         Error (OpLoc, NoENDC);    /* ENDC is missing! */
  526.  
  527.     break;
  528.  
  529.     case IfEQ:                        /* IFEQ */
  530.     ObjSrc = GetValue (SrcOp, SrcLoc);
  531.     if (ObjSrc != 0)
  532.         SkipNest++;            /* Skip to the next ENDC. */
  533.     break;
  534.  
  535.     case IfNE:                        /* IFNE */
  536.     ObjSrc = GetValue (SrcOp, SrcLoc);
  537.     if (ObjSrc == 0)
  538.         SkipNest++;
  539.     break;
  540.  
  541.     case IfGT:                        /* IFGT */
  542.     ObjSrc = GetValue (SrcOp, SrcLoc);
  543.     if (ObjSrc <= 0)
  544.         SkipNest++;
  545.     break;
  546.  
  547.     case IfGE:                        /* IFGE */
  548.     ObjSrc = GetValue (SrcOp, SrcLoc);
  549.     if (ObjSrc < 0)
  550.         SkipNest++;
  551.     break;
  552.  
  553.     case IfLT:                        /* IFLT */
  554.     ObjSrc = GetValue (SrcOp, SrcLoc);
  555.     if (ObjSrc >= 0)
  556.         SkipNest++;
  557.     break;
  558.  
  559.     case IfLE:                        /* IFLE */
  560.     ObjSrc = GetValue (SrcOp, SrcLoc);
  561.     if (ObjSrc > 0)
  562.         SkipNest++;
  563.     break;
  564.  
  565.     case IfC:                        /* IFC */
  566.     if (strcmp (SrcOp, DestOp) != 0)
  567.         SkipNest++;
  568.     break;
  569.  
  570.     case IfNC:                        /* IFNC */
  571.     if (strcmp (SrcOp, DestOp) == 0)
  572.         SkipNest++;
  573.     break;
  574.  
  575.     case IfD:                        /* IFD */
  576.     if (ReadSymTab (SrcOp))
  577.         AddRef (LineCount);
  578.     if (DefLine2 > LineCount)
  579.         SkipNest++;
  580.     break;
  581.  
  582.     case IfND:                        /* IFND */
  583.     if (ReadSymTab (SrcOp))
  584.         AddRef (LineCount);
  585.     if (DefLine2 <= LineCount)
  586.         SkipNest++;
  587.     break;
  588.  
  589.     case EndC:                        /* ENDC */
  590.     break;                /* LineParts will take care of it. */
  591.  
  592.     case Section:                    /* SECTION */
  593.     if (SFormat)
  594.         Error (OpLoc, NotSFmt);    /* Not in S-format */
  595.     tempop[0] = '\0';
  596.     s = Line + DestLoc + strlen (DestOp);    /* Check for flags. */
  597.     if (*s == ',') {
  598.         s++;
  599.         GetField (s, tempop);    /* Get specification. */
  600.     }
  601.     DoSection (SrcOp, SrcLoc, DestOp, DestLoc, tempop, j);
  602.     break;
  603.  
  604.     case CSeg:                        /* CODE */
  605.     if (SFormat)
  606.         Error (OpLoc, NotSFmt);    /* Not in S-format */
  607.     DoSection (SrcOp, SrcLoc, "CODE", OpLoc, DestOp, DestLoc);
  608.     break;                /* Treat as SECTION. */
  609.  
  610.     case DSeg:                        /* DATA */
  611.     if (SFormat)
  612.         Error (OpLoc, NotSFmt);    /* Not in S-format */
  613.     DoSection (SrcOp, SrcLoc, "DATA", OpLoc, DestOp, DestLoc);
  614.     break;                /* Treat as SECTION. */
  615.  
  616.     case BSS:                        /* BSS */
  617.     if (SFormat)
  618.         Error (OpLoc, NotSFmt);    /* Not in S-format */
  619.     DoSection (SrcOp, SrcLoc, "BSS", OpLoc, DestOp, DestLoc);
  620.     break;                /* Treat as SECTION. */
  621.  
  622.     case Idnt:                        /* IDNT */
  623.     s = Line + SrcLoc;
  624.     if ((*s == '"') || (*s == '\''))
  625.         s++;            /* Ignore quotes. */
  626.     t = IdntName;
  627.     while (!isspace(*s)
  628.     && (*s != '"')
  629.     && (*s != '\'')
  630.     && (*s != '\0'))
  631.         *t++ = *s++;
  632.     *t = '\0';
  633.     break;
  634.  
  635.     case DCB:                        /* DCB */
  636.     if ((Size == Word) || (Size == Long))
  637.         AddrCnt = AddrBndW (AddrCnt);
  638.     DupFact = GetValue (SrcOp, SrcLoc);    /* Replication factor */
  639.     if (DefLine2 >= LineCount) {
  640.         Error (SrcLoc, FwdRef);    /* Illegal forward reference */
  641.         DupFact = 0;
  642.     }
  643.     if (Hunk2 != ABSHUNK) {
  644.         Error (SrcLoc, AbsReq);    /* Must be absolute! */
  645.         DupFact = 0;
  646.     }
  647.     ObjDest = GetValue (DestOp, DestLoc);    /* Value to replicate */
  648.     Dest.Hunk = Hunk2;
  649.     if (Size == 4) {
  650.         ObjString[nX++] = (ObjDest >> 24) & 0x00FF;
  651.         ObjString[nX++] = (ObjDest >> 16) & 0x00FF;
  652.     }
  653.     if (Size >= 2)
  654.         ObjString[nX++] = (ObjDest >> 8) & 0x00FF;
  655.     ObjString[nX++] = ObjDest & 0x00FF;
  656.  
  657.     AddrAdv = InstSize = nX;
  658.     if (Dest.Hunk != ABSHUNK) {        /* Relocatable */
  659.         templong = AddrCnt;
  660.         for (i = 0; i < DupFact; i++) {
  661.         PutRel (templong, Hunk2, Size);    /* Generate a relocation     */
  662.         templong += nX;            /*  entry for each constant. */
  663.         }
  664.     }
  665.     PrntAddr = MakeHunk = TRUE;
  666.     break;
  667.  
  668.     case Equr:                        /* EQUR */
  669.     if ((i = IsRegister (SrcOp, strlen (SrcOp))) < 0)
  670.         Error (SrcLoc, AddrErr);    /* Not a valid register. */
  671.     if (Label[0] == '\0')
  672.         Error (0, NeedLab);        /* Need a label */
  673.     else {
  674.         if (!ReadSymTab (Label))    /* Make a new entry. */
  675.         AddSymTab (Label, (long) i, 0L, LineCount, 0x20);
  676.         GotEqur = TRUE;        /* We have at least one EQUR. */
  677.     }
  678.     break;
  679.  
  680.     case Reg:                        /* REG */
  681.     if (Label[0] == '\0')
  682.         Error (0, NeedLab);        /* Need a label */
  683.     else {
  684.         if ((i = GetMultReg (SrcOp, SrcLoc)) == 0) {
  685.         Error (SrcLoc, OperErr);
  686.         } else {
  687.         if (!ReadSymTab    (Label)) {    /* Make a new entry. */
  688.             AddSymTab (Label, (long) i, 0L, LineCount, 0x40);
  689.             GotEqur = TRUE;        /* We have at least one EQUR. */
  690.         }
  691.         }
  692.     }
  693.     break;
  694.  
  695.     case Near:                        /* NEAR */
  696.     if (SrcOp[0] == '\0') {
  697.         SmallData = 4;        /* Default to register A4. */
  698.     } else {            /* Get register specification. */
  699.         SmallData = IsRegister (SrcOp, strlen (SrcOp)) - 8;
  700.         if ((SmallData < 0) || (SmallData > 6)) {
  701.         Error (SrcLoc,AddrErr);    /* It's not a valid register. */
  702.         SmallData = -1;        /* Disable small-data model. */
  703.         }
  704.     }
  705.     AnyNear    = TRUE;    /* Remember that we use small data somewhere. */
  706.     break;
  707.  
  708.     case Far:                        /* FAR */
  709.     SmallData = -1;        /* Reset small-data model flag. */
  710.     break;
  711.  
  712.     default:
  713.     break;
  714.     }
  715.  
  716.     return (Dir);
  717. }
  718.  
  719.  
  720.  
  721. DoSection (name, nameloc, type, typeloc, flags, flagloc)
  722. char *name, *type, *flags;
  723. int nameloc, typeloc, flagloc;
  724. /* Processes SECTION directive or equivalent. */
  725. {
  726.     static long HunkPos;    /* Seek address of start of section */
  727.     register char *s, *t;
  728.     long newflags, templong;
  729.     char tempop[MAXLINE];
  730.     int  i;
  731.  
  732.     PrntAddr = TRUE;
  733.  
  734.     if (HunkType != HunkNone) {
  735.     FwdLim1     = FwdBranch;    /* Clear forward branch controls. */
  736.     FwdFixLimit = FwdBranchFix;
  737.     }
  738.  
  739.     for (s = type; *s; s++)        /* Convert section type */
  740.     *s = toupper (*s);        /*  to upper case. */
  741.     if ((type[0] == '\0') || (strcmp (type, "CODE") == 0))
  742.     newflags = HunkCode;        /* Code section */
  743.     else if (strcmp (type, "DATA") == 0)
  744.     newflags = HunkData;        /* Data section */
  745.     else if (strcmp (type, "BSS") == 0)
  746.     newflags = HunkBSS;        /* BSS section */
  747.     else {
  748.     Error (typeloc, OperErr);    /* Invalid type */
  749.     strcpy (type, "CODE");
  750.     newflags = HunkCode;        /* Make it CODE. */
  751.     }
  752.     newflags <<= 16;    /* Shift to high-order 16 bits. */
  753.  
  754.     if (flags[0]) {
  755.     for (s = flags; *s; s++)        /* Convert flags */
  756.         *s = toupper (*s);            /*  to upper case. */
  757.     if (strcmp (flags, "CHIP") == 0)
  758.         newflags |= MEMF_CHIP;        /* CHIP memory */
  759.     else if (strcmp (flags, "FAST") == 0)
  760.         newflags |= MEMF_FAST;        /* FAST memory */
  761.     else
  762.         Error (flagloc, OperErr);        /* Invalid - ignore. */
  763.     }
  764.  
  765.     templong = (newflags & 0xFFFF0000) >> 16;
  766.     sprintf (tempop,"  %4x",HunkSeq++);    /* Make section name unique. */
  767.     s = name;
  768.     if ((*s == '"') || (*s == '\''))
  769.     s++;                /* Ignore quotes. */
  770.     t = tempop + 6;
  771.     while (!isspace(*s)
  772.     && (*s != '"')
  773.     && (*s != '\'')
  774.     && (*s != '\0'))
  775.     *t++ = *s++;            /* Concatenate section name. */
  776.     *t = '\0';
  777.  
  778.     if (ReadSymTab (tempop)) {        /* Scan for section name. */
  779.     if (HunkType == HunkNone) {
  780.         SectLine = 1;        /* Start of first section */
  781.     } else {
  782.         if (Pass2) {
  783.         AddRef (LineCount);
  784.         DumpSdata (&Srec);    /* Finish the previous hunk. */
  785.         if (!MakeHunk) {    /* If it was a null hunk, */
  786.             xwrite (&Srec);    /* overwrite it.  */
  787.             lseek (Srec.fd, HunkPos, 0);
  788.             Srec.Ptr = Srec.Buf;
  789.         }
  790.         } else {
  791.         AddrCnt = AddrBndL (AddrCnt);    /* Finish on long word. */
  792.         }
  793.         if (AddrCnt > OrgHigh)
  794.         Sect->Val = AddrCnt;    /* End of old section */
  795.         else
  796.         Sect->Val = OrgHigh;    /* We've ORGed higher. */
  797.         SectLine = LineCount;    /* Start of new section */
  798.     }
  799.     Sect = Sym;            /* Point to new section. */
  800.     if (Dir != Org)
  801.         AddrCnt = Sym->Val;        /* Continuation */
  802.     SectStart = OrgHigh = AddrCnt;
  803.     OrgFlag = FALSE;
  804.     TempAddr = StartAddr = AddrCnt;
  805.     CurrHunk = Sym->Hunk & 0x0000FFFFL;    /* Hunk number */
  806.     HunkType = (Sym->Hunk & 0x3FFF0000L) >> 16;    /* Type */
  807.     HunkFlags = Sym->Hunk & 0xC0000000L;        /* Flags */
  808.     if (Pass2 && !SFormat) {        /* Start a new hunk. */
  809.         HunkPos = lseek (Srec.fd, 0L, 1);
  810.         HunkPos += Srec.Ptr - Srec.Buf;    /* It starts here. */
  811.         templong = HunkName;
  812.         xputl (&Srec, templong);
  813.         if (tempop[6])
  814.         DumpName (&Srec, &tempop[6], 0L);    /* Hunk name */
  815.         else
  816.         DumpName (&Srec, " ", 0L);
  817.         xputl (&Srec, HunkType | HunkFlags);    /* Hunk type */
  818.         LenPtr = Srec.Ptr;        /* Pointer to hunk length */
  819.         LenPos = lseek (Srec.fd, 0L, 1);
  820.         LenPos += LenPtr-Srec.Buf;    /* Hunk length goes here. */
  821.         xputl (&Srec, 0L);        /* For now, set it to zero. */
  822.     }
  823.     MakeHunk = FALSE;        /* We don't have anything yet. */
  824.     if (AnyNear && (CurrHunk > 1))
  825.         Error (OpLoc, ManySect);    /* Too many hunks for small data! */
  826.     return;
  827.     }
  828.  
  829.     AddrCnt = AddrBndL (AddrCnt);    /* Finish on long word bounary. */
  830.  
  831.     if (Pass2) {
  832.     Error (OpLoc, ManySect);    /* Table overflowed in pass 1! */
  833.     return;
  834.     }
  835.     if (NextHunk >= ABSHUNK)        /* Set up a new table entry. */
  836.     return;                /* Section table overflow */
  837.  
  838.     if (HunkType != HunkNone) {
  839.     if (AddrCnt > OrgHigh)
  840.         Sect->Val = AddrCnt;    /* End of old section */
  841.     else
  842.         Sect->Val = OrgHigh;    /* We've ORGed higher. */
  843.     SectLine = LineCount;        /* Starting line number */
  844.     } else {
  845.     SectLine = 1;            /* Start of first section */
  846.     }
  847.     if (Dir != Org)
  848.     AddrCnt = 0L;            /* Reset location counter. */
  849.     SectStart = OrgHigh = AddrCnt;
  850.     OrgFlag = FALSE;
  851.     TempAddr = StartAddr = AddrCnt;
  852.     HunkType = (newflags & 0x3FFF0000L) >> 16;    /* Type */
  853.     HunkFlags = newflags & 0xC0000000L;        /* Flags */
  854.     CurrHunk = NextHunk++;        /* Bump next hunk number. */
  855.     newflags |= CurrHunk;        /* Add hunk number to flags. */
  856.     AddSymTab (tempop, AddrCnt, newflags, LineCount, 16);    /* New entry */
  857.     Sect = Sym;                /* Pointer to new entry */
  858.     MakeHunk = FALSE;            /* We don't have anything yet. */
  859.     if (AnyNear && (CurrHunk > 1))
  860.     Error (OpLoc, ManySect);    /* Too many hunks for small data! */
  861.     return;
  862. }
  863.